﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Http;
using ELearning.BLL;
using ELearning.Common;
using ELearning.Common.CommonStr;
using ELearning.Common.Extensions;
using ELearning.Common.Helpers;
using ELearning.Common.Model;
using ELearning.Models;
using ELearning.Models.ViewModel.User;

namespace ELearning.API.Controllers.YTJYAdminController
{
    /// <summary>
    /// 学生控制器
    /// </summary>
    public class StudentController : BaseApiController
    {
        /// <summary>
        /// 用户操作service
        /// </summary>
        protected ESysUserService userService = new ESysUserService();

        /// <summary>
        /// 组织操作service
        /// </summary>
        protected EOrgService orgService = new EOrgService();

        /// <summary>
        /// 用于与套餐关联操作service
        /// </summary>
        private TUserPackageService tUserPackageService => new TUserPackageService();

        /// <summary>
        /// 用户角色关联操作service
        /// </summary>
        protected RRoleUserService RoleUserService = new RRoleUserService();

        /// <summary>
        /// 邀请码日志操作service
        /// </summary>
        private TInviteCodeLogService tInviteCodeLogService => new TInviteCodeLogService();

        /// <summary>
        /// 获取用户列表
        /// </summary>
        [HttpPost, Route("api/Student/GetUserList")]
        public ServiceResponse<GetUserViewModel> GetUserList(GetUserRequest request)
        {
            var orgCode = CurrentUserModel.OrgCode;
            if (orgCode != CommonConst.DEFAULT_ORGCODE)//如果不是平台用户，则只能看到自己学校的用户列表
                request.OrgCode = orgCode;

            var viewModel = new GetUserViewModel();
            var userPage = userService.GetUserList(request);
            if (userPage != null)
            {
                viewModel.TotalCount = userPage.TotalItems.ObjToInt();
                var userIds = userPage.Items.Select(u => u.UserID);
                var ruList = RoleUserService.FindList(r => userIds.Contains(r.UserID)).ToList();

                foreach (var user in userPage.Items)
                {
                    var u = user.MapTo<GetUserItem, ESysUser>();
                    u.CreateTime = user.CreateTime.ToString("yyyy-MM-dd HH:mm");
                    u.ModifyTime = user.ModifyTime;
                    u.ConfirmPassword = u.Password = user.Password;
                    u.ShowHeadPhoto = PictureHelper.GetFileFullPath(u.HeadPhoto);
                    u.Sex = SexHelper.SexToStr(user.Sex);
                    var temp = ruList.Where(r => r.UserID == u.UserId).Select(r => r.RoleID).ToList();
                    u.RoleIdList.AddRange(temp);
                    viewModel.UserItems.Add(u);
                }
            }

            return ServiceResponse<GetUserViewModel>.SuccessResponse("success", viewModel);
        }

        /// <summary>
        /// 添加用户
        /// </summary>
        [HttpPost, Route("api/Student/AddUser")]
        public ServiceResponse<GetUserItem> AddUser(GetUserItem userItem)
        {
            var user = new ESysUser
            {
                UserID = Guid.NewGuid(),
                AccountStatus = 1,
                Birthday = userItem.Birthday,
                CreateTime = DateTime.Now,
                Creater = CurrentUserModel.LoginName,
                Company = userItem.Company,
                Department = userItem.Department,
                Email = userItem.Email,
                HeadPhoto = userItem.HeadPhoto,
                IsDelete = false,
                ModifyTime = DateTime.Now,
                Position = userItem.Position,
                MobilePhone = userItem.MobilePhone,
                Remark = userItem.Remark,
                LoginName = userItem.LoginName,
                UserName = userItem.UserName,
                UserType = UserType.UserTypeSTUDENT,
                OfficeTel = userItem.OfficeTel,
                OrgCode = userItem.OrgCode ?? CommonConst.DEFAULT_ORGCODE,
                Password = userItem.Password,
                //Password = DESProvider.EncryptString(userItem.Password),
                Sex = SexHelper.SexToInt(userItem.Sex)
            };
            if (string.IsNullOrEmpty(user.HeadPhoto))
                user.HeadPhoto = CommonConst.UserDefaultHeadPhoto;
            if (string.IsNullOrEmpty(user.Remark))
                user.Remark = CommonConst.UserDefaultRemark;

            var temp = userService.FindList(t => !t.IsDelete && t.LoginName.Equals(user.LoginName));
            if (temp.Any())
                return ServiceResponse<GetUserItem>.SuccessResponse("用户登录名已存在，请重新输入", userItem, CommonConst.Code_OprateError);

            var inviteCode = GetInviteCode(user.OrgCode, user.UserID);

            user.InviteCode = inviteCode;

            #region 关联套餐与用户

            if (userItem.PackageIdList.IsNotNull() && userItem.PackageIdList.Any())
            {
                foreach (var packageId in userItem.PackageIdList)
                {
                    var rpu = new TUserPackage
                    {
                        Id = Guid.NewGuid(),
                        CreateTime = DateTime.Now,
                        CreateUserId = CurrentUserModel.UserId,
                        IsDelete = false,
                        OrderId = Guid.Empty,
                        PackageId = packageId,
                        SourceType = 1,
                        UpdateTime = DateTime.Now,
                        UpdateUserId = CurrentUserModel.UserId,
                        UserId = user.UserID
                    };
                    tUserPackageService.AddNoSaveChange(rpu);
                }
            }

            #endregion

            var u = userService.Add(user);

            userItem.UserId = user.UserID;
            return ServiceResponse<GetUserItem>.SuccessResponse("success", userItem);
        }

        /// <summary>
        /// 更新用户
        /// </summary>
        [HttpPost, Route("api/Student/UpdateUser")]
        public ServiceResponse<GetUserItem> UpdateUser(GetUserItem userItem)
        {
            var user = userService.GetUserById(userItem.UserId);
            user.AccountStatus = 1;
            user.Birthday = userItem.Birthday;
            user.Company = userItem.Company;
            user.Department = userItem.Department;
            user.Email = userItem.Email;
            user.HeadPhoto = userItem.HeadPhoto;
            user.OrgCode = userItem.OrgCode ?? CommonConst.DEFAULT_ORGCODE;
            user.ModifyTime = DateTime.Now;
            user.Position = userItem.Position;
            user.MobilePhone = userItem.MobilePhone;
            user.Remark = userItem.Remark;
            user.UserName = userItem.UserName;
            user.OfficeTel = userItem.OfficeTel;
            user.Sex = SexHelper.SexToInt(userItem.Sex);
            if (string.IsNullOrEmpty(user.HeadPhoto))
                user.HeadPhoto = CommonConst.UserDefaultHeadPhoto;
            if (string.IsNullOrEmpty(user.Remark))
                user.Remark = CommonConst.UserDefaultRemark;

            var temp = userService.FindList(t => !t.IsDelete && t.LoginName.Equals(user.LoginName) && user.UserID != t.UserID);
            if (temp.Any())
                return ServiceResponse<GetUserItem>.SuccessResponse("用户登录名已存在，请重新输入", userItem, CommonConst.Code_OprateError);

            #region 关联套餐与用户

            var rpus = tUserPackageService.FindList(x => !x.IsDelete && x.UserId == user.UserID).ToList();

            if (userItem.PackageIdList.IsNotNull() && userItem.PackageIdList.Any())
            {
                foreach (var packageId in userItem.PackageIdList)
                {
                    if (rpus.Any(r => r.PackageId == packageId))//说明数据库中存在，不执行操作
                    {

                    }
                    else//数据库中不存在，则插入
                    {
                        var rpu = new TUserPackage
                        {
                            Id = Guid.NewGuid(),
                            CreateTime = DateTime.Now,
                            CreateUserId = CurrentUserModel.UserId,
                            IsDelete = false,
                            OrderId = Guid.Empty,
                            PackageId = packageId,
                            SourceType = 1,
                            UpdateTime = DateTime.Now,
                            UpdateUserId = CurrentUserModel.UserId,
                            UserId = user.UserID
                        };
                        tUserPackageService.AddNoSaveChange(rpu);
                    }
                }
            }

            //删除本次未关联的
            var dels = rpus.Where(x => !x.IsDelete && !userItem.PackageIdList.Contains(x.PackageId)).ToList();
            tUserPackageService.DeletesNoSaveChange(dels);

            #endregion

            var u = userService.Update(user);

            return ServiceResponse<GetUserItem>.SuccessResponse("success", userItem);
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id">用户id</param>
        [HttpPost, Route("api/Student/DeleteUser")]
        public ServiceResponse<int> DeleteUser(Guid id)
        {
            var user = userService.Find(u => !u.IsDelete && u.UserID == id);
            user.IsDelete = true;
            user.AccountStatus = 0;
            var rus = RoleUserService.FindList(r => r.UserID == user.UserID).ToList();
            if (rus.Any())
                RoleUserService.DeletesNoSaveChange(rus);

            var b = userService.Update(user);
            return ServiceResponse<int>.SuccessResponse(1);
        }

        /// <summary>
        /// 用户名是否存在
        /// </summary>
        [HttpGet, Route("api/Student/IsExistUser")]
        public ServiceResponse<bool> IsExistUser(Guid id, string loginName)
        {
            var user = userService.Find(u => !u.IsDelete && u.UserID != id && u.LoginName == loginName);
            var r = user == null;
            return ServiceResponse<bool>.SuccessResponse(r);
        }

        /// <summary>
        /// 获取注册用户列表
        /// </summary>
        [HttpPost, Route("api/Student/GetRegesterList")]
        public ServiceResponse<GetUserViewModel> GetRegesterList(GetUserRequest request)
        {
            var viewModel = new GetUserViewModel();
            var userPage = userService.GetRegesterList(request);
            if (userPage != null)
            {
                viewModel.TotalCount = userPage.TotalItems.ObjToInt();
                var orgCodes = userPage.Items.Select(u => u.OrgCode).ToList();
                var orgs = orgService.FindList(o => orgCodes.Contains(o.org_code)).ToList();
                var userIds = userPage.Items.Select(x => x.UserID).ToList();
                var rpus = tUserPackageService.FindList(x => !x.IsDelete && userIds.Contains(x.UserId)).ToList();
                foreach (var user in userPage.Items)
                {
                    var u = new GetUserItem
                    {
                        UserId = user.UserID,
                        AccountStatus = user.AccountStatus,
                        Birthday = user.Birthday,
                        CreateTime = user.CreateTime.ToString("yyyy-MM-dd HH:mm"),
                        Company = user.Company,
                        Creater = user.Creater,
                        Department = user.Department,
                        Email = user.Email,
                        HeadPhoto = user.HeadPhoto,
                        LoginName = user.LoginName,
                        ModifyTime = user.ModifyTime,
                        MobilePhone = user.MobilePhone,
                        Position = user.Position,
                        Remark = user.Remark,
                        UserName = user.UserName,
                        UserType = user.UserType,
                        OrgCode = user.OrgCode,
                        OrgName = orgs.FirstOrDefault(r => r.org_code == user.OrgCode)?.org_name ?? string.Empty,
                        OfficeTel = user.OfficeTel,
                        Password = user.Password,
                        ConfirmPassword = user.Password,
                        Sex = SexHelper.SexToStr(user.Sex),
                        PackageIdList = rpus.Where(x => x.UserId == user.UserID).Select(x => x.PackageId).ToList()
                    };
                    u.ShowHeadPhoto = PictureHelper.GetFileFullPath(u.HeadPhoto);
                    viewModel.UserItems.Add(u);
                }
            }

            return ServiceResponse<GetUserViewModel>.SuccessResponse("success", viewModel);
        }

        /// <summary>
        /// 修改用户启用/禁用状态
        /// </summary>
        [HttpPost, Route("api/Student/ChangeUserStatus")]
        public ServiceResponse<int> ChangeUserStatus(Guid id, bool status)
        {
            var user = userService.Find(u => !u.IsDelete && u.UserID == id);
            user.AccountStatus = status ? 1 : 0;
            var r = userService.Update(user);
            return ServiceResponse<int>.SuccessResponse(1);
        }

        /// <summary>
        /// 导入学生
        /// </summary>
        [HttpPost, Route("api/Student/InsertSGMWAdminUsers")]
        public object InsertSGMWAdminUsers(string userType)
        {
            var result = CommonConst.UploadFailDefaultUrl;
            var filelist = HttpContext.Current.Request.Files;
            var users = new List<ESysUser>();
            var path = HttpContext.Current.Server.MapPath("/ImportConfig/sgmwConfig.xml");
            var xr = XMLHelper.ReadToHashtable(path);
            if (filelist.Count > 0)
            {
                for (var i = 0; i < filelist.Count; i++)
                {
                    var file = filelist[i];
                    var fileName = file.FileName;
                    var fn = fileName.Split('\\');
                    if (fn.Length > 1)
                    {
                        fileName = fn[fn.Length - 1];
                    }
                    DataTable dataTable = null;
                    var fs = fileName.Split('.');
                    if (fs.Length > 1)
                    {
                        var ext = fs[fs.Length - 1];
                        if (ext == "xlsx")
                            dataTable = ExcelHelp.ExcelToTableForXLSX(file.InputStream, xr.ImportHashtable); //excel转成datatable
                        else
                            dataTable = ExcelHelp.ExcelToTableForXLS(file.InputStream); //excel转成datatable
                    }
                    //users = dataTable.ToDataList<InsertSGMWAdminUsersViewModel>(); //datatable转成list
                    users = dataTable.ToDataList<ESysUser>(); //datatable转成list
                }
            }
            var succe = new List<ESysUser>();
            var faile = new List<ESysUser>();
            var exportList = new List<ESysUser>();
            var names = userService.FindList(u => !u.IsDelete).Select(u => u.LoginName).ToList();
            //数据list转成数据库实体对应的list
            foreach (var u in users)
            {
                u.UserID = GuidUtil.NewSequentialId();
                u.UserType = userType;
                u.OrgCode = CurrentUserModel.OrgCode ?? CommonConst.UserDefaultOrgCode;
                u.Password = CommonConst.UserDefaultPsw;
                u.HeadPhoto = CommonConst.UserDefaultHeadPhoto;
                u.AccountStatus = 1;
                u.InviteCode = GetInviteCode(u.OrgCode, u.UserID);
                u.CreateTime = DateTime.Now;
                u.ModifyTime = DateTime.Now;
                u.Creater = CurrentUserModel.LoginName ?? string.Empty;
                u.Modifyer = CurrentUserModel.LoginName ?? string.Empty;
                if (string.IsNullOrEmpty(u.LoginName) || string.IsNullOrEmpty(u.MobilePhone) || string.IsNullOrEmpty(u.UserName))
                {
                    u.Remark = "登录名/姓名/移动电话必填";
                    faile.Add(u);
                    exportList.Add(u);
                    continue;
                }

                var t = names.Where(f => f == u.LoginName);
                var p1 = succe.Where(o => o.LoginName == u.LoginName);
                if (t.Any() || p1.Any())
                {
                    u.Remark = "登录名重复";
                    exportList.Add(u);
                    faile.Add(u);
                }
                else
                {
                    succe.Add(u);
                }
            }
            var dt = succe.ToDataTable(null);
            dt.TableName = "ESysUser";
            var r = succe.Count;
            SqlBulkCopyHelper.SaveTable(dt);

            var url = string.Empty;
            if (exportList.Any())
            {
                var extDt = exportList.ToDataTable(xr.ExportHashtable);
                var str = GetSavePath();
                var strs = str.Split(',');
                if (strs.Any() && strs.Length > 1)
                {
                    var fileFullPath = strs[0];
                    url = strs[1];
                    ExcelHelp.TableToExcelForXLSX(extDt, fileFullPath);
                }
            }

            var list = new { failed = faile.Take(100).ToList(), failedCount = faile.Count }; //数据太多的话，浏览器会崩溃

            if (r == users.Count)
            {
                var json = new { list, msg = "添加用户成功", url };
                return ServiceResponse<object>.SuccessResponse(json);
            }
            else if (r > 0)
            {
                var json = new { list, msg = ("添加用户成功" + r + "人；失败" + (users.Count - r) + "人"), url };
                return ServiceResponse<object>.SuccessResponse(json);
            }
            else
            {
                var json = new { list, msg = "添加用户失败", url };
                return ServiceResponse<object>.SuccessResponse(CommonConst.OprateFailStr, json);
            }
        }

        /// <summary>
        /// 获取文件保存路径
        /// </summary>
        private string GetPath()
        {
            var str = string.Empty;
            var virtualPath = "/UploadFile/Files/";
            var path = HttpContext.Current.Server.MapPath(virtualPath);
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            var fileFullPath = $"{path}{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            return fileFullPath;
        }

        private string GetSavePath()
        {
            var virtualPath = "/UploadFile/Files/ImportFail/";
            var path = HttpContext.Current.Server.MapPath(virtualPath);
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            var fn = $"失败信息{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            var fileFullPath = $"{path}{fn}";
            return $"{fileFullPath},{fn}";
        }

        [HttpGet, Route("api/Student/SetCode")]
        [AllowAnonymous]
        public object SetCode()
        {
            var i = 0;
            var users = userService.FindList(o => !o.IsDelete).ToList();
            foreach (var user in users)
            {
                var inviteCode = $"{CodeHelper.CreateCodePre()}{i.ToString().PadLeft(8, '0')}";

                //邀请码生成成功，存入数据库
                tInviteCodeLogService.AddNoSaveChange(new TInviteCodeLog
                {
                    Id = Guid.NewGuid(),
                    CreateTime = DateTime.Now,
                    UpdateTime = DateTime.Now,
                    IsDelete = false,
                    CreateUserId = CurrentUserModel.UserId,
                    UpdateUserId = CurrentUserModel.UserId,
                    InviteCode = inviteCode,
                    OrgCode = user.OrgCode,
                    UserId = user.UserID,
                    Sort = i
                });
                i++;
                user.InviteCode = inviteCode;
                userService.UpdateNoSaveChange(user);
            }

            userService.SaveChange();
            return true;
        }

        [HttpGet, Route("api/Student/SetOrgCode")]
        [AllowAnonymous]
        public object SetOrgCode()
        {
            var i = tInviteCodeLogService.FindList(p => !p.IsDelete).OrderByDescending(p => p.Sort).FirstOrDefault()?.Sort ?? 0;
            var orgs = orgService.FindList(o => !o.IsDelete).ToList();
            foreach (var org in orgs)
            {
                var inviteCode = $"{CodeHelper.CreateCodePre()}{i.ToString().PadLeft(8, '0')}";

                //邀请码生成成功，存入数据库
                tInviteCodeLogService.AddNoSaveChange(new TInviteCodeLog
                {
                    Id = Guid.NewGuid(),
                    CreateTime = DateTime.Now,
                    UpdateTime = DateTime.Now,
                    IsDelete = false,
                    CreateUserId = CurrentUserModel.UserId,
                    UpdateUserId = CurrentUserModel.UserId,
                    InviteCode = inviteCode,
                    OrgCode = org.org_code,
                    UserId = Guid.Empty,
                    Sort = i
                });
                i++;
                org.InviteCode = inviteCode;
                orgService.UpdateNoSaveChange(org);
            }

            orgService.SaveChange();
            return true;
        }

    }
}